/**
  ******************************************************************************
  * File Name          : USART.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/

#include "tskcfg.h"
#include "cat1.h"
#include "bsp.h"

//#define CAT1_UART_TO_TTY

extern void Cat1_CmdRcvISR(uint8_t dat);
extern void Cat1_CmdTimISR(void);
extern void Cat1_LinkISR(void);
extern void Network_ReceiveISR(uint8_t dat);

/* UART5 init function */

void Cat1_BspDeinit(void)
{	
  /* enable GPIO clock */
  rcu_periph_clock_enable(RCU_GPIOD);
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOE);
	rcu_periph_clock_enable(RCU_SYSCFG);
	
	rcu_periph_clock_disable(RCU_USART1);
	
	
	gpio_mode_set(CAT1_RST_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, CAT1_RST_Pin);
	gpio_output_options_set(CAT1_RST_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, CAT1_RST_Pin);
	
	gpio_mode_set(CAT1_PWR_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, CAT1_PWR_Pin);
	gpio_output_options_set(CAT1_PWR_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, CAT1_PWR_Pin);

	gpio_mode_set(CAT1_LINKA_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, CAT1_LINKA_Pin);
	
	Cat1_Power(0);
  Cat1_Reset(0);
  
	gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_5);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
	
	gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_6);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
	
	/* USART configure */
	usart_deinit(USART1);
  
	usart_interrupt_disable(USART1, USART_INT_RBNE);
	usart_interrupt_disable(USART1, USART_INT_RT);

	nvic_irq_disable(USART1_IRQn);
	
	usart_disable(USART1);
}

void Cat1_BspInit(void)
{	
  /* enable GPIO clock */
	rcu_periph_clock_enable(RCU_GPIOD);
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOE);
	rcu_periph_clock_enable(RCU_SYSCFG);
	
	rcu_periph_clock_enable(RCU_USART1);
	
	
	gpio_mode_set(CAT1_RST_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, CAT1_RST_Pin);
	gpio_output_options_set(CAT1_RST_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, CAT1_RST_Pin);
	
	gpio_mode_set(CAT1_PWR_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, CAT1_PWR_Pin);
	gpio_output_options_set(CAT1_PWR_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, CAT1_PWR_Pin);

	gpio_mode_set(CAT1_LINKA_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, CAT1_LINKA_Pin);
	syscfg_exti_line_config(EXTI_SOURCE_GPIOB, EXTI_SOURCE_PIN7);
	
	exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
	exti_interrupt_flag_clear(EXTI_7);
	
	
	gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);
	gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);
	
	gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_5);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
	
	gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
	
	/* USART configure */
	usart_deinit(USART1);
	usart_baudrate_set(USART1, 115200U);
	usart_word_length_set(USART1, USART_WL_8BIT);
	usart_parity_config(USART1, USART_PM_NONE);
	usart_stop_bit_set(USART1, USART_STB_1BIT);
	usart_receive_config(USART1, USART_RECEIVE_ENABLE);
	usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
	usart_halfduplex_disable(USART1);
	usart_synchronous_clock_disable(USART1);
	
  usart_receiver_timeout_threshold_config(USART1, 1500); /* 86.806ms */
	usart_receiver_timeout_enable(USART1);
  
	usart_interrupt_enable(USART1, USART_INT_RBNE);
	usart_interrupt_enable(USART1, USART_INT_RT);

	nvic_irq_enable(EXTI5_9_IRQn, CAT1_IO_IRQ_PRIORITY,    0);
	nvic_irq_enable(USART1_IRQn,  CAT1_UART_IRQ_PRIORITY,  0);
	
	usart_enable(USART1);
}

void Cat1_UartSendBuf(const uint8_t *buf, uint32_t len)
{
	uint32_t i;
  
	for(i=0; i<len; i++)
	{
    USART_DATA(USART1) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(USART1) & USART_STAT0_TBE));

#ifdef CAT1_UART_TO_TTY
		USART_DATA(UART4) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART4) & USART_STAT0_TBE));
#endif
	}
}

void Cat1_UartSendStr(const char *buf)
{
	uint32_t i;
  
	for(i=0; buf[i]!='\0'; i++)
	{
    USART_DATA(USART1) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(USART1) & USART_STAT0_TBE));

#ifdef CAT1_UART_TO_TTY
		USART_DATA(UART4) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART4) & USART_STAT0_TBE));
#endif
	}
}

/**
  * @brief This function handles UART3 global interrupt.
  */
void USART1_IRQHandler(void)
{	
	if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) != RESET)
	{
		if(Cat1_WorkMode != CAT1_MODE_TRS)
		{
			Cat1_CmdRcvISR(USART_DATA(USART1));
		}
		else
		{
			Network_ReceiveISR(USART_DATA(USART1));
		}
		
#ifdef CAT1_UART_TO_TTY
		USART_DATA(UART4) = USART_DATA(USART1);
    while(!(USART_STAT0(UART4) & USART_STAT0_TBE));
#endif
	}
  
  if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RT) != RESET)
	{
		usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RT);
		
		if(Cat1_WorkMode != CAT1_MODE_TRS)
		{
			Cat1_CmdTimISR();
		}
	}
}

void EXTI5_9_IRQHandler(void)
{
	if(exti_interrupt_flag_get(EXTI_7) != RESET)
  {
    EXTI_PD = (uint32_t)EXTI_7;
		
		Cat1_LinkISR();
  }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
